#include <string>
#include "bcmiFacade.h"
#include "../CommonUsed/TMatrix.h"
#include "../LGBPLib/LGBPExtractor.h"
#include "../LGBPFacePredictor/FaceGenderPredictor.h"
#pragma comment(lib, "LGBPLib.lib")
#pragma comment(lib, "LGBPFacePredictor.lib")
#pragma comment(lib, "BCMICommon.lib")

using namespace std;
using namespace cv;

vector<float>& BCMIGender::extractLGBPFeature( const IplImage* img, int iBlockX, int iBlockY,
		int faceOrient, int featureSelection)
{
	if (faceOrient == -1)
		faceOrient = _PM00;
	FAST::TMatrix<MappingFeatureType> *matAlpha = NULL;
	LGBPExtractor extractor( iBlockX, iBlockY, matAlpha, featureSelection);
	int nBinNum = extractor.nBinNum;
	//the create and copy may can be optimized
	IplImage* singleChannelImage = cvCreateImage(cvSize(img->width, img->height),
		IPL_DEPTH_8U, 1);
	if( img->nChannels == 1 )
		cvCopy(img, singleChannelImage);
	else if( img->nChannels == 3 )
		cvCvtColor(img, singleChannelImage, CV_BGR2GRAY);

	extractor.ExtractFeatures(singleChannelImage, faceOrient);

	//mat.SetRowVect(i,extractor.getRawMat()->GetRowVect(0));
	int featureLength = GABOR_SCALE*GABOR_ORIENT * iBlockX*iBlockY * 
		nBinNum*MULTILEVELS/(featureSelection+1);
	if (extractor.getRawMat()->GetCols() != featureLength)
		printf("Error! Feature Length does not match.\n");

	feature.resize(featureLength);

	cout << "sizeof(feature): " << sizeof(&feature[0]) << endl;
	cout << "sizeof(*feature): " << sizeof(feature[0]) << endl;
	cout << "len*sizeof(float): " << featureLength*sizeof(float) << endl;

	memcpy_s(&feature[0], sizeof(&feature[0]), extractor.getOutMat()->GetData(), 
		featureLength*sizeof(float));
	//extractor.getRawMat()->GetRowPtr(0),extractor.getRawMat()->GetCols()
	return feature;
}

BCMIGender::BCMIGender( void )
{
	genderPredictor = NULL;
}

BCMIGender::~BCMIGender( void )
{
	if (genderPredictor != NULL)
		delete genderPredictor;
}

int BCMIGender::predict( const IplImage* img )
{
	Gender res = genderPredictor->Predict(img);
	return res;
}

void BCMIGender::loadPredictor( std::string alphaFN, std::string modelFN, std::string rangeFN )
{
	if (NULL != genderPredictor) {
		delete genderPredictor;
		genderPredictor = NULL;
	}
	genderPredictor = new FaceGenderPredictor(
		alphaFN.c_str(), modelFN.c_str(), rangeFN.c_str());
}
